# -*- coding: UTF-8 -*-
from twisted.internet import reactor, protocol
from twisted.protocols import basic
max_limit = 1024 * 1024 * 1024

# 连接池
conn_pool = {}


def send(addr, data):
    conn = conn_pool.get(addr)
    if conn:
        conn.send(data)


def build_addr_key(addr):
    return f"{addr.type}:{addr.host}:{addr.port}"


def split_bytes(data, delimiter):
    # 根据指定的字节拆分字节数据
    parts = []
    start = 0
    while True:
        index = data.find(delimiter, start)
        if index == -1:
            break
        parts.append(data[start:index])
        start = index + len(delimiter)
    parts.append(data[start:])
    return parts


class LJProtocol():
    def __init__(self, listen, delimiter=b'\n'):
        # 指定分隔符字符，这里使用换行符作为分隔符
        self.delimiter = delimiter
        # 用于缓存未完整接收的数据
        self.buffer = b""
        # 制定监听器
        self.listen = listen

    def on_msg(self, msg):
        # 将接收到的数据添加到缓存中
        self.buffer += msg
        # 字符串截取
        self.buffer = self.buffer[:max_limit]
        # 字符串拆分
        parts = split_bytes(self.buffer, self.delimiter)
        # 移除最后一个元素并赋值
        self.buffer = parts.pop()

        # 执行监听
        for item in parts:
            self.listen(item)


class LJServer(protocol.Protocol):
    def __init__(self, addr, protocol):
        self.protocol = protocol
        self.addr = addr

    def connectionMade(self):
        # 连接对象放入连接池
        conn_pool[self.addr] = self
        print(f"LJ - 连接接入 - {self.addr}")

    def send(self, data):
        # 发送响应数据
        self.transport.write(data)

    def dataReceived(self, data):
        # 调用解析器
        if self.protocol:
            # 调用监听
            self.protocol.on_msg(data)

    def connectionLost(self, reason):
        print(f"LJ - 连接断开 - {self.addr}")


class MyServerFactory(protocol.Factory):
    def __init__(self, protocol):
        self.protocol = protocol

    def buildProtocol(self, addr):
        """创建链接对象
        Args:
            addr (Str): 地址类型
        Returns:
            LJServer: 链接对象
        """
        # 创建并返回链接对象给框架使用
        return LJServer(build_addr_key(addr), self.protocol)


def init(port=8888, protocol=None):
    reactor.listenTCP(port, MyServerFactory(protocol))
    print(f"LJ 端口监听启动 - {port}")
    reactor.run()


# 启动服务器
if __name__ == "__main__":
    def listen(data):
        print(data)
    init(8888, LJProtocol(listen))
